package com.hh.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hh.common.ErrorCode;
import com.hh.entity.domain.Follow;
import com.hh.entity.domain.User;
import com.hh.exception.BusinessException;
import com.hh.mapper.FollowMapper;
import com.hh.service.FollowService;
import com.hh.service.UserService;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author hanhui
 * @description 针对表【follow】的数据库操作Service实现
 * @createDate 2025-08-02 16:54:40
 */
@Service
public class FollowServiceImpl extends ServiceImpl<FollowMapper, Follow>
        implements FollowService {

    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    UserService userService;

    /**
     * 处理关注操作
     * @param loginUserId 当前登录用户ID
     * @param followUserId 被关注用户ID
     * @return 是否成功
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean doFollow(Long loginUserId, Long followUserId) {

        // 查询关注关系
//        boolean isFollow = this.lambdaQuery()
//                .eq(Follow::getUserId, loginUserId)
//                .eq(Follow::getFollowUserId, followUserId)
//                .exists();
        // 检查用户ID的有效性
//        if (loginUserId == null || followUserId == null) {
//            throw new BusinessException(ErrorCode.PARAMS_ERROR);
//        }
        //外键约束
        User followUser = userService.getById(followUserId);
        if (followUser== null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"用户不存在");
        }
        Boolean hasFollow = hasFollow(loginUserId, followUserId);
        if (Boolean.TRUE.equals(hasFollow)) {
            //取消关注
            boolean remove = this.remove(new QueryWrapper<Follow>()
                    .eq("followUserId", followUserId)
                    .eq("userId", loginUserId)
            );
            if (Boolean.FALSE.equals(remove)) {
                throw new BusinessException(ErrorCode.OPERATION_ERROR);
            }
            //从redis中移除
            stringRedisTemplate.opsForSet().remove("follows:" + loginUserId, followUserId.toString());
            return remove;
        } else {
            //关注
            Follow follow = new Follow();
            follow.setUserId(loginUserId);
            follow.setFollowUserId(followUserId);
            boolean save = this.save(follow);
            if (Boolean.FALSE.equals(save)) {
                throw new BusinessException(ErrorCode.OPERATION_ERROR);
            }
            //存入redis
            stringRedisTemplate.opsForSet().add("follows:" + loginUserId, followUserId.toString());
            return save;
        }
    }

    /**
     * 判断用户是否关注
     * @param userId 用户ID
     * @param followUserId 被关注用户ID
     * @return 是否关注
     */
    @Override
    public Boolean hasFollow(Long userId, Long followUserId) {
        // 查询关注关系
        return stringRedisTemplate.opsForSet()
                .isMember("follows:" + userId, followUserId.toString());
    }

    /**
     * 获取用户关注列表
     * @param userId 用户ID
     * @return 关注列表
     */
    @Override
    public List<Long> getFollowList(Long userId) {
        return Objects.requireNonNull(stringRedisTemplate.opsForSet().members("follows:" + userId))
                .stream()
                .map(Long::valueOf)
                .collect(Collectors.toList());
    }
}




